/*
 * MIT许可证
 *
 * 版权所有 (c) 2025-2035 JacobGreen
 *
 * 特此免费授予获得本软件及相关文档文件（"软件"）副本的任何人不受限制地处置该软件的权利，
 * 包括不限于使用、复制、修改、合并、发布、分发、再许可和/或出售该软件副本，
 * 以及允许被提供该软件的人这样做，须遵守以下条件：
 *
 * 上述版权声明和本许可声明应包含在该软件的所有副本或实质性部分中。
 *
 * 本软件按"原样"提供，不附带任何形式的明示或暗示的保证，
 * 包括但不限于对适销性、特定用途适用性和不侵权的保证。
 * 在任何情况下，作者或版权持有人均不对任何索赔、损害或其他
 * 责任负责，无论是在合同行为、侵权行为或其他方面，
 * 与软件或软件的使用或其他交易有关。
 */

/**
 * filename:ArrayList.h
 * description:是数组表的API接口
 */
#ifndef _ARRAY_LIST_H_
#define _ARRAY_LIST_H_

#include <stdbool.h>

// 默认初始容量
#define DEFAULT_CAPACITY 10
// 扩容倍数
#define EXPAND_FACTOR 2

/**
 * 数组表结构体
 */
typedef struct ArrayList
{
    // 属性
    void **data;  // 数据指针数组，使用void型指针作为泛型
    int size;     // 当前数据数量
    int capacity; // 数组容量

    //操作

    // 数据操作

    /**
     * <p>
     * 向数组表末尾添加一个元素
     * </p>
     * 
     * @param data 要添加的元素指针
     * @return 是否添加成功
     */
    bool (*add)(struct ArrayList *list, void *data);
    /**
     * <p>
     * 从数组表中移除指定元素
     * </p>
     * 
     * @param data 要移除的元素指针
     * @param compare 比较函数指针
     * @return 是否移除成功
     */
    bool (*remove)(struct ArrayList *self, void *data, int (*compare)(void *, void *));
    /**
     * <p>
     * 判断数组表是否包含指定元素
     * </p>
     * 
     * @param data 要判断的元素指针
     * @param compare 比较函数指针
     * @return 是否包含指定元素
     */
    bool (*contains)(struct ArrayList *self, void *data, int (*compare)(void *, void *));
    /**
     * <p>
     * 获取数组表中指定元素的第一个出现位置索引
     * </p>
     * 
     * @param data 要获取索引的元素指针
     * @param compare 比较函数指针
     * @return 第一个出现位置索引，若不存在则返回-1
     */
    int (*indexOf)(struct ArrayList *self, void *data, int (*compare)(void *, void *));
    /**
     * <p>
     * 获取数组表中指定元素的最后一个出现位置索引
     * </p>
     * 
     * @param data 要获取索引的元素指针
     * @param compare 比较函数指针
     * @return 最后一个出现位置索引，若不存在则返回-1
     */
    int (*lastIndexOf)(struct ArrayList *self, void *data, int (*compare)(void *, void *));
    /**
     * <p>
     * 用指定元素替换数组表中所有满足条件的元素
     * </p>
     * 
     * @param data 要替换的元素指针
     * @param compare 比较函数指针
     */
    void (*replaceAll)(struct ArrayList *self, void *data, bool (*compare)(void *, void *));

    // 索引操作

    /**
     * <p>
     * 在数组表的指定位置插入一个元素
     * </p>
     * 
     * @param index 要插入的位置索引
     * @param data 要插入的元素指针
     * @return 是否插入成功
     */
    bool (*addIndex)(struct ArrayList *self, int index, void *data);
    /**
     * <p>
     * 添加元素到数组表的第一个位置
     * </p>
     * 
     * @param data 要添加的元素指针
     * @return 是否添加成功
     */
    bool (*addFirst)(struct ArrayList *self, void *data);
    /**
     * <p>
     * 在数组表的末尾添加一个元素
     * </p>
     * 
     * @param data 要添加的元素指针
     * @return 是否添加成功
     */
    bool (*addLast)(struct ArrayList *self, void *data);
    /**
     * <p>
     * 删除数组表中指定位置的元素
     * </p>
     * 
     * @param index 要删除的位置索引
     * @return 被删除的元素指针
     */
    void *(*removeIndex)(struct ArrayList *self, int index);
    /**
     * <p>
     * 删除数组表的第一个元素
     * </p>
     * 
     * @return 被删除的元素指针
     */
    void *(*removeFirst)(struct ArrayList *self);
    /**
     * <p>
     * 删除数组表的最后一个元素
     * </p>
     * 
     * @return 被删除的元素指针
     */ 
    void *(*removeLast)(struct ArrayList *self);
    /**
     * <p>
     * 在数组表的指定位置替换一个元素
     * </p>
     * 
     * @param index 要替换的位置索引
     * @param data 要替换的元素指针
     * @return 被替换的元素指针
     */
    void *(*set)(struct ArrayList *self, int index, void *data);
    /**
     * <p>
     * 设置数组表的第一个元素
     * </p>
     * 
     * @param data 要设置的元素指针
     * @return 被设置的元素指针
     */
    void *(*setFirst)(struct ArrayList *self, void *data);
    /**
     * <p>
     * 设置数组表的最后一个元素
     * </p>
     * 
     * @param data 要设置的元素指针
     * @return 被设置的元素指针
     */
    void *(*setLast)(struct ArrayList *self, void *data);
    /**
     * <p>
     * 获取数组表中指定位置的元素
     * </p>
     * 
     * @param index 要获取的位置索引
     * @return 元素指针
     */
    void *(*get)(struct ArrayList *self, int index);
    /**
     * <p>
     * 获取数组表的第一个元素
     * </p>
     * 
     * @return 第一个元素指针
     */
    void *(*getFirst)(struct ArrayList *self);
    /**
     * <p>
     * 获取数组表的最后一个元素
     * </p>
     * 
     * @return 最后一个元素指针
     */
    void *(*getLast)(struct ArrayList *self);

    // 集合操作
    
    /**
     * <p>
     * 向数组表末尾添加另一个数组表的所有元素
     * </p>
     * 
     * @param other 另一个数组表指针
     * @return 是否添加成功
     */
    bool (*addAll)(struct ArrayList *self, struct ArrayList *other);
    /**
     * <p>
     * 从数组表中移除另一个数组表的所有元素
     * </p>
     * 
     * @param other 另一个数组表指针
     * @param compare 比较函数指针
     * @return 是否移除成功
     */
    bool (*removeAll)(struct ArrayList *self, struct ArrayList *other, int (*compare)(void *, void *));
    /**
     * <p>
     * 保留数组表中与另一个数组表相同的元素，移除其他元素
     * </p>
     * 
     * @param other 另一个数组表指针
     * @param compare 比较函数指针
     * @return 是否保留成功
     */
    bool (*retainAll)(struct ArrayList *self, struct ArrayList *other, int (*compare)(void *, void *));
    /**
     * <p>
     * 判断数组表是否包含另一个数组表的所有元素
     * </p>
     * 
     * @param other 另一个数组表指针
     * @param compare 比较函数指针
     * @return 是否包含另一个数组表的所有元素
     */
    bool (*containsAll)(struct ArrayList *self, struct ArrayList *other, int (*compare)(void *, void *));
    /**
     * <p>
     * 合并数组表，将另一个数组表的所有元素添加到当前数组表的末尾
     * </p>
     * 
     * @param other 另一个数组表指针
     * @return 是否合并成功
     */
    bool (*merge)(struct ArrayList *self, struct ArrayList *other);
    /**
     * <p>
     * 判断数组表是否与另一个数组表相等
     * </p>
     * 
     * @param other 另一个数组表指针
     * @param compare 比较函数指针
     * @return 是否相等
     */
    bool (*equals)(struct ArrayList *self, struct ArrayList *other, int (*compare)(void *, void *));
    /**
     * <p>
     * 创建数组表的一个深拷贝
     * </p>
     * 
     * @return 深拷贝的数组表指针
     */
    struct ArrayList *(*clone)(struct ArrayList *self);
    /**
     * <p>
     * 获取数组表中指定范围的子数组表
     * </p>
     * 
     * @param fromIndex 子数组表的起始索引(包含)
     * @param toIndex 子数组表的结束索引(不包含)
     * @return 子数组表指针
     */
    struct ArrayList *(*subList)(struct ArrayList *self, int fromIndex, int toIndex);
    /**
     * <p>
     * 将数组表从指定索引位置拆分为两个子数组表,
     * 第一个子数组表包含从起始索引到拆分索引位置的元素(包含拆分索引位置的元素),
     * 第二个子数组表包含从拆分索引位置+1到结束索引的元素(不包含结束索引的元素)
     * 第一个子数组的地址是原数组表的地址，数据截取(不复制)；第二个子数组的地址是新分配的内存地址，数据深拷贝
     * </p>
     * 
     * @param index 拆分索引位置
     * @return 包含两个子数组表指针的数组
     */
    struct ArrayList **(*split)(struct ArrayList *self, int index);
    /**
     * <p>
     * 将数组表分组，根据指定的分组函数
     * </p>
     * 
     * @param group 分组函数指针
     * @return 分组后的数组表指针数组
     */ 
    struct ArrayList **(*group)(struct ArrayList *self, int (*group)(void *));
    
    // 列表操作

    /**
     * <p>
     * 将数组表转换为字符串
     * </p>
     * @param self 数组表指针
     * @return 字符串指针
     */
    char *(*toString)(struct ArrayList *self);
    /**
     * <p>
     * 获取数组表的哈希码
     * </p>
     * 
     * @return 哈希码
     */
    int (*hashCode)(struct ArrayList *self);
    /**
     * <p>
     * 判断数组表是否为空
     * </p>
     * 
     * @return 是否为空
     */
    bool (*isEmpty)(struct ArrayList *self);
    /**
     * <p>
     * 在数组表的指定位置添加另一个数组表的所有元素
     * </p>
     * 
     * @param index 要添加的位置索引
     * @param other 另一个数组表指针
     * @return 是否添加成功
     */
    bool (*addAllIndex)(struct ArrayList *self, int index, struct ArrayList *other);
    /**
     * <p>
     * 删除数组表中指定范围的元素
     * </p>
     * 
     * @param fromIndex 要删除的范围起始索引(包含)
     * @param toIndex 要删除的范围结束索引(不包含)
     * @return 是否删除成功
     */
    bool (*removeRange)(struct ArrayList *self, int fromIndex, int toIndex);
    /**
     * <p>
     * 截断数组表，将其大小设置为指定值
     * </p>
     * 
     * @param newSize 新的大小
     * @return 是否截断成功
     */
    bool (*truncate)(struct ArrayList *self, int newSize);
    /**
     * <p>
     * 清空数组表，将所有元素设为NULL
     * </p>
     * 
     */
    bool (*clear)(struct ArrayList *self);
    /**
     * <p>
     * 对数组表中的每个元素执行指定操作
     * </p>
     * 
     * @param visit 操作函数指针
     */
    void (*forEach)(struct ArrayList *self, void (*visit)(void *));
    /**
     * <p>
     * 对数组表中的每个元素执行指定操作(逆序)
     * </p>
     * 
     * @param visit 操作函数指针
     */
    void (*forEachReverse)(struct ArrayList *self, void (*visit)(void *));
    /**
     * <p>
     * 反转数组表中的元素顺序
     * </p>
     * 
     */
    void (*reverse)(struct ArrayList *self);
    /**
     * <p>
     * 对数组表中的元素进行排序
     * </p>
     * 
     * @param type 排序类型(0:升序, 1:降序)
     * @param compare 比较函数指针
     */
    void (*sort)(struct ArrayList *self, int type, int (*compare)(void *, void *));

    //属性操作

    /**
     * <p>
     * 获取数组表的大小(元素数量)
     * </p>
     * 
     * @return 数组表的大小
     */
    int (*getSize)(struct ArrayList *self);
    /**
     * <p>
     * 获取数组表的当前容量
     * </p>
     * 
     * @return 当前容量
     */
    int (*getCapacity)(struct ArrayList *self);
    /**
     * <p>
     * 确保数组表的容量不小于指定值
     * </p>
     * 
     * @param minCapacity 最小容量
     */
    bool (*ensureCapacity)(struct ArrayList *self, int minCapacity);
} ArrayList;

/**
 * 创建一个新的ArrayList
 * @param capacity 初始容量
 * @return ArrayList指针
 */
struct ArrayList *arrayListInit(int capacity);

/**
 * 销毁ArrayList
 * @param list ArrayList指针
 */
void arrayListDestroy(struct ArrayList *list);

#endif // _ARRAY_LIST_H_
